package net.yxsoft.service.infrastructure;

import com.jfinal.aop.Before;
import com.jfinal.kit.HashKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.Ret;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import net.yxsoft.enumclass.StateEnumCls;
import net.yxsoft.kit.Helper;
import net.yxsoft.kit.RSAKit;
import net.yxsoft.kit.StringHashKit;
import net.yxsoft.model.infrastructure.TsRole;
import net.yxsoft.model.infrastructure.TsUser;
import net.yxsoft.bean.UserSearchModel;
import net.yxsoft.quorum.QuorumKit;
import net.yxsoft.resource.Res;
import net.yxsoft.resource.RetRes;
import net.yxsoft.service.common.BaseService;
import rapid.core.Authuser;
import rapid.core.ContextStateEnum;
import rapid.core.TResult;
import rapid.util.StrKit;

import java.math.BigInteger;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2016/5/26.
 */
public class UserService extends BaseService {

  public static final UserService INSTANCE = new UserService();



  public TsUser findById(String id) {
    return TsUser.dao.findById(id);
  }

  /**
  * @MethodName: findUserRoles
  * @Description:
  * @param: userId
  * @return * @return java.util.List<java.lang.String>
  * @throws
  * @date 2023/8/31 13:34
  * @author wj
  */
  public List<String> findUserRoles(String userId){

    List<String> roleIds = Db.query("select b.code from ts_ur_relation a,ts_role b where a.role_id = b.id and user_id = ?", userId);
    return  roleIds;
  }

  /**
  * @MethodName: addUser
  * @Description: 新增人员信息
  * @param: model
   * @param: sessionUser
  * @return * @return rapid.core.TResult
  * @throws
  * @date 2023/8/31 13:35
  * @author wj
  */
  public TResult addUser(TsUser model, Authuser sessionUser) {
    String operation = "";
    //判断当前添加的登录账号在系统中是否存在
    TsUser isExist = TsUser.dao.findFirst("SELECT * FROM TS_USER WHERE LOGIN_ID=?", model.getLoginId());
    if(model.getCardId() != null){
      List<TsUser> tsUserList  = TsUser.dao.find("SELECT * FROM TS_USER WHERE card_id=?",model.getCardId());
      if(tsUserList.size() > 0){
        return TResult.fail().msg("当前身份证号已存在");
      }
    }
    if(isExist != null) {
      //登录名已存在
      return TResult.fail().msg("用户名已存在");
    }
    String salt = model.getLoginId();
    String hashedPass = HashKit.sha256(salt + Res.USER_DEFAULT_PASSWORD);

    model.setPassword(hashedPass);
    Timestamp time = new Timestamp(new java.util.Date().getTime());
    model.setCreatorId(sessionUser.getId());
    model.setCreatorName(sessionUser.getName());
    model.setCreateTime(time);
    model.setEditorId(sessionUser.getId());
    model.setEditorName(sessionUser.getName());
    model.setUpdateTime(time);
    model.setId(Helper.bulidUUID());
    Ret ret = RSAKit.generatorRSA();
    model.setRSAPrivateKey(ret.get(RetRes.PRIVATE_KEY).toString());
    model.setRSAPublicKey(ret.get(RetRes.PUBLIC_KEY).toString());


    operation = "新增";
    boolean _r = model.save();
    String strLog =  "主键：" + sessionUser.getId() + "，名称：" + sessionUser.getName() + "，新增用户名称：" + model.getName()  ;
    if(_r) {

      //保存成功
      log(sessionUser.getLoginId(), sessionUser.getName(), "系统管理/用户管理", operation, sessionUser.getLoginId(), strLog);
      return TResult.success();
    } else {
      //保存失败
      return TResult.fail().msg("保存失败");
    }
  }
  




  /**
  * @MethodName: updateUser
  * @Description: 修改人员信息
  * @param: model
   * @param: sessionUser
  * @return * @return rapid.core.TResult
  * @throws 
  * @date 2023/8/31 13:36
  * @author wj 
  */
  public TResult updateUser(TsUser model, Authuser sessionUser) {
    String operation =  "";
    //判断当前修改的信息，是否还存在
    TsUser _dbmodel = TsUser.dao.findById(model.getId());
//    TsUser isExist = TsUser.dao.findFirst("SELECT * FROM TS_USER WHERE LOGIN_ID=?", model.getLoginId());
    if(model.getCardId() != null){
      List<TsUser> tsUserList  = TsUser.dao.find("SELECT * FROM TS_USER WHERE card_id=? and id <> ?",model.getCardId(),model.getId());
      if(tsUserList.size() > 0){
        return TResult.fail().msg("当前身份证号已存在");
      }
    }
//    if(isExist != null) {
//      //登录名已存在
//      return TResult.fail().msg("用户名已存在");
//    }
    if(_dbmodel == null) {
      //信息不存在
      return TResult.fail().msg("当前信息已被删除，不可修改。");
    }
    Timestamp time = new Timestamp(new java.util.Date().getTime());
    _dbmodel.setLoginId(model.getLoginId());
    _dbmodel.setName(model.getName());
    //_dbmodel.setCode(model.getCode());
    _dbmodel.setSex(model.getSex());
    _dbmodel.setPhone(model.getPhone());
    _dbmodel.setQq(model.getQq());
    _dbmodel.setUserTyp(model.getUserTyp());
    //_dbmodel.setAvatar(model.getAvatar());
    _dbmodel.setNote(model.getNote());
    _dbmodel.setEditorId(sessionUser.getId());
    _dbmodel.setEditorName(sessionUser.getName());
    _dbmodel.setUpdateTime(time);
    _dbmodel.setEnabled(model.getEnabled());
    _dbmodel.setCanlogin(model.getCanlogin());
    _dbmodel.setCardId(model.getCardId());
//    _dbmodel.setTabname(model.getTabname());
    _dbmodel.setOrg(model.getOrg());
    _dbmodel.setDept(model.getDept());
    _dbmodel.setRowId(model.getRowId());
    _dbmodel.setImei(model.getImei());
    _dbmodel.setIs_staff(model.getIs_staff());


    _dbmodel.setTrustAccount(model.getTrustAccount());
    _dbmodel.setTrustName(model.getTrustName());
    boolean _r = _dbmodel.update();
    operation = "修改";
    String strLog = "主键：" + sessionUser.getId() + "，名称：" + sessionUser.getName() + "，被修改用户名称：" + model.getName() ;
    if(_r) {
      //保存成功
      log(sessionUser.getLoginId(), sessionUser.getName(), "系统管理/用户管理", operation, sessionUser.getLoginId(), strLog);
      return TResult.success();
    } else {
      //保存失败
      return TResult.fail().msg("保存失败");
    }
  }

  /**
  * @MethodName: removeUsers
  * @Description: 
  * @param: ids
  * @return * @return boolean
  * @throws 
  * @date 2023/8/31 13:36
  * @author wj 
  */
  @Before(Tx.class)
  public boolean removeUsers(String[] ids) throws SQLException {
    if(ids.length > 0) {
      TsUser user;
      for(String id : ids) {
        user = TsUser.dao.findById(id);
        if(user.getLoginId().equals("_admin")) {
          continue;
        }
        if(!user.delete()) {
          throw new SQLException();
        }
      }
    }
    return true;
  }

  /**
  * @MethodName: getAllRoleInfo
  * @Description:
  * @param:
  * @return * @return java.util.List<net.yxsoft.model.infrastructure.TsRole>
  * @throws
  * @date 2023/8/31 13:36
  * @author wj
  */
  public List<TsRole> getAllRoleInfo() {
    List<TsRole> _rolelist = TsRole.dao.find("SELECT * FROM TS_ROLE ORDER BY NAME");
    return _rolelist;
  }

  /**
  * @MethodName: getUserRoleRelationByUserId
  * @Description:
  * @param: userId
  * @return * @return java.util.List<net.yxsoft.model.infrastructure.TsRole>
  * @throws
  * @date 2023/8/31 13:36
  * @author wj
  */
  public List<TsRole> getUserRoleRelationByUserId(String userId) {
    List<TsRole> list = new ArrayList<>();
    list = TsRole.dao.find("SELECT r.id , r.name FROM TS_UR_RELATION  u left join ts_role r on u.role_id = r.id WHERE u.USER_ID=?", userId);
    return list;
  }

  /**
  * @MethodName: setUserRoleRelation
  * @Description:
  * @param: userId
   * @param: roleIds
   * @param: sessionUser
  * @return * @return rapid.core.TResult
  * @throws
  * @date 2023/8/31 13:36
  * @author wj
  */
  @Before(Tx.class)
  public TResult setUserRoleRelation(String userId, String[] roleIds,Authuser sessionUser) {
    String operation = "";
    String str = "";
    TResult result = new TResult();
    List<String> _strsql = new ArrayList<String>();

    _strsql.add(String.format("DELETE FROM TS_UR_RELATION WHERE USER_ID='%s'", userId));

    if(roleIds != null && roleIds.length > 0) {
      for(String s : roleIds) {
        _strsql.add(String.format("INSERT INTO TS_UR_RELATION(USER_ID,ROLE_ID) VALUES('%s','%s')", userId, s));
        str += s + ",";
      }
    }
    Db.batch(_strsql, 10000);
    operation = "设置角色";
    String strLog = "主键：" + sessionUser.getId() + "，名称：" + sessionUser.getName()+ ",设置角色userId："+ userId + "，角色ID："+ str;
    log(sessionUser.getLoginId(), sessionUser.getName(), "系统管理/用户管理", operation, sessionUser.getLoginId(),strLog);
    result.setState(ContextStateEnum.SUCCESS);
    result.setMessage("角色保存成功.");
    return result;
  }

  /**
  * @MethodName: getUserGroupRelationByUserId
  * @Description:
  * @param: userId
  * @return * @return java.util.List<java.lang.String>
  * @throws
  * @date 2023/8/31 13:37
  * @author wj
  */
  public List<String> getUserGroupRelationByUserId(String userId) {
    List<String> _Uglist = Db.query("SELECT GROUP_ID FROM TS_UG_RELATION WHERE USER_ID=?", userId);
    return _Uglist;
  }

   /**
   * @MethodName: setUserGroupRelation
   * @Description:
   * @param: userId
    * @param: groupIds
    * @param: sessionUser
   * @return * @return rapid.core.TResult
   * @throws
   * @date 2023/8/31 13:37
   * @author wj
   */
  @Before(Tx.class)
  public TResult setUserGroupRelation(String userId, String[] groupIds,Authuser sessionUser) {
    String operation = "";
    TResult result = new TResult();
    List<String> _strsql = new ArrayList<String>();

    _strsql.add(String.format("DELETE FROM TS_UG_RELATION WHERE USER_ID='%s'", userId));

    if(groupIds != null && groupIds.length > 0) {
      for(String g : groupIds) {
        if(StrKit.hasValue(g)) {
          _strsql.add(String.format("INSERT INTO TS_UG_RELATION(USER_ID,GROUP_ID) VALUES('%s','%s')", userId, g));
        }
      }
    }
    Db.batch(_strsql, 10000);
    operation = "设置机构";
    String strLog = "主键：" + sessionUser.getId() + "，名称：" + sessionUser.getName()+ ",设置机构userId："+ userId + "，机构ID："+ groupIds;
    log(sessionUser.getLoginId(), sessionUser.getName(), "系统管理/用户管理", operation, sessionUser.getLoginId(),strLog);
    result.setState(ContextStateEnum.SUCCESS);
    result.setMessage("机构保存成功.");
    return result;
  }

  /**
  * @MethodName: getUserGroupDataRelationByUserId
  * @Description: 
  * @param: userId
  * @return * @return java.util.List<java.lang.String>
  * @throws 
  * @date 2023/8/31 13:37
  * @author wj 
  */
  public List<String> getUserGroupDataRelationByUserId(String userId) {
    List<String> _Uglist = Db.query("SELECT GROUP_ID FROM TS_UDP_RELATION WHERE USER_ID=?", userId);
    return _Uglist;
  }

  /**
  * @MethodName: findUserGroups
  * @Description: 
  * @param: uid
  * @return * @return java.util.List<com.jfinal.plugin.activerecord.Record>
  * @throws 
  * @date 2023/8/31 13:37
  * @author wj 
  */
  public List<Record> findUserGroups(String uid) {
    return Db.find(Db.getSqlPara("user.findGroups", uid));
  }

  /**
  * @MethodName: setUserGroupDataRelation
  * @Description: 
  * @param: userId
   * @param: groupIds
  * @return * @return int
  * @throws 
  * @date 2023/8/31 13:37
  * @author wj 
  */
  @Before(Tx.class)
  public int setUserGroupDataRelation(String userId, String[] groupIds) {

    List<String> _strsql = new ArrayList<String>();

    _strsql.add(String.format("DELETE FROM TS_UDP_RELATION WHERE USER_ID='%s'", userId));

    if(groupIds != null && groupIds.length > 0) {
      for(String g : groupIds) {
        _strsql.add(String.format("INSERT INTO TS_UDP_RELATION(USER_ID,GROUP_ID) VALUES('%s','%s')", userId, g));
      }
    }
    Db.batch(_strsql, 10000);

    return 0;
  }

  /**
  * @MethodName: changeState
  * @Description:
  * @param: userids
   * @param: state
   * @param: sessionUser
  * @return * @return int
  * @throws
  * @date 2023/8/31 13:38
  * @author wj
  */
  @Before(Tx.class)
  public int changeState(String[] userids, StateEnumCls state,Authuser sessionUser) {
    String operation = "";
    String strLogIds = "";
    List<String> _sqlList = new ArrayList<String>();
    for(int i = 0; i < userids.length; i++) {
      //判断当前添加的用户系统中是否存在
      TsUser _isExist = TsUser.dao.findFirst("SELECT * FROM TS_USER WHERE ID=?", userids[i]);
      if(_isExist == null) {
        //用户已存在
        return -1;
      }
      String salt = _isExist.getLoginId();
      strLogIds += salt+ ",";
      _sqlList.add(String.format("UPDATE TS_USER SET ENABLED='%s' WHERE ID = '%s'", state.getValue(), userids[i]));
    }
    Db.batch(_sqlList, 10000);
    operation = "更改状态";
    String strLog = "主键：" + sessionUser.getId() + "，名称：" + sessionUser.getName() + ",更改状态LoginId："+strLogIds;
    log(sessionUser.getLoginId(), sessionUser.getName(), "系统管理/用户管理", operation, sessionUser.getLoginId(),strLog);

    return 0;
  }

  /**
  * @MethodName: changeLogin
  * @Description:
  * @param: userids
   * @param: _statestr
   * @param: sessionUser
  * @return * @return int
  * @throws
  * @date 2023/8/31 13:38
  * @author wj
  */
  @Before(Tx.class)
  public int changeLogin(String[] userids, String _statestr,Authuser sessionUser) {
    String operation = "";
    String strLogIds = "";
    List<String> _sqlList = new ArrayList<String>();
    for(int i = 0; i < userids.length; i++) {
      //判断当前添加的用户系统中是否存在
      TsUser _isExist = TsUser.dao.findFirst("SELECT * FROM TS_USER WHERE ID=?", userids[i]);
      if(_isExist == null) {
        //用户已存在
        return -1;
      }
      String salt = _isExist.getLoginId();
      strLogIds += salt+ ",";
      _sqlList.add(String.format("UPDATE TS_USER SET CANLOGIN='%s' WHERE ID = '%s'", _statestr, userids[i]));
    }
    Db.batch(_sqlList, 10000);
    operation = "修改登录状态";
    String strLog = "主键：" + sessionUser.getId() + "，名称：" + sessionUser.getName() + ",修改登录状态LoginId："+strLogIds;
    log(sessionUser.getLoginId(), sessionUser.getName(), "系统管理/用户管理", operation, sessionUser.getLoginId(),strLog);
    return 0;
  }

  /**
  * @MethodName: resetPassword
  * @Description:
  * @param: userids
   * @param: sessionUser
  * @return * @return int
  * @throws
  * @date 2023/8/31 13:38
  * @author wj
  */
  @Before(Tx.class)
  public int resetPassword(String[] userids,Authuser sessionUser) {
    String operation = "";
    String str = "";
    List<String> _sqlList = new ArrayList<String>();
    for(int i = 0; i < userids.length; i++) {
      //判断当前添加的用户系统中是否存在
      TsUser _isExist = TsUser.dao.findFirst("SELECT * FROM TS_USER WHERE ID=?", userids[i]);
      if(_isExist == null) {
        //用户已存在
        return -1;
      }
      String salt = _isExist.getLoginId();
      str += salt;
      String hashedPass = HashKit.sha256(salt + Res.USER_DEFAULT_PASSWORD);

      _sqlList.add(String.format("UPDATE TS_USER SET PASSWORD='%s' WHERE ID = '%s'", hashedPass, userids[i]));
    }
    Db.batch(_sqlList, 10000);
    operation = "重置密码";
    String strLog = "主键：" + sessionUser.getId() + "，名称：" + sessionUser.getName()+ ",重置密码LoginId："+str ;
    log(sessionUser.getLoginId(), sessionUser.getName(), "系统管理/用户管理", operation, sessionUser.getLoginId(),strLog);
    return 0;
  }


  /**
  * @MethodName: exportUsers
  * @Description: 导出
  * @param: searchModel
  * @return * @return java.util.List<net.yxsoft.model.infrastructure.TsUser>
  * @throws
  * @date 2023/8/31 13:38
  * @author wj
  */
  public List<TsUser> exportUsers(UserSearchModel searchModel) {
    StringBuilder _strsql = new StringBuilder();
    _strsql.append("SELECT\n" +
                     "  U.ID,\n" +
                     "  U.LOGIN_ID,\n" +
                     "  U.CODE,\n" +
                     "  U.NAME,\n" +
                     "  r.NAME roleName,\n" +
                     "  U.AVATAR,\n" +
                     "  CASE U.ENABLED WHEN '1' THEN '启用' ELSE '禁用' END  ENABLED_CN,\n" +
                     "  U.LAST_LOGIN_TIME,\n" +
                     "  U.LAST_LOGIN_IP,\n" +
                     "  CASE U.user_typ WHEN '0' THEN '管理员' ELSE U.user_typ END user_typ_cn,\n"+
                     "  CASE U.SEX WHEN '1' THEN '男' ELSE '女' END SEX_CN,\n" +
                     "  CODE1.CODENAME AS USERTYPE_CN,\n" +
                     "  CASE WHEN CODE2.CODENAME IS NULL THEN ' ' ELSE CODE2.CODENAME END USERCODE_CN" +
                     "  FROM TS_USER U\n" +
                     "          LEFT OUTER JOIN TS_UG_RELATION UG ON UG.USER_ID = U.ID\n" +
                     "          LEFT OUTER JOIN TS_UR_RELATION UR ON UR.USER_ID = U.ID\n" +
                     "          left join ts_role r on r.id=UR.role_id\n" +
                     "          LEFT OUTER JOIN ( SELECT * FROM TS_CODE WHERE PARENTNAME = ? ) CODE1 ON U.USER_TYP=CODE1.CUSTOMID\n" +
                     "          LEFT OUTER JOIN ( SELECT * FROM TS_CODE WHERE PARENTNAME = ? ) CODE2 ON U.CODE=CODE2.CUSTOMID\n" +
                     "          WHERE 1=1 ");

    List<String> _where = new ArrayList<String>();

    _where.add("人员类型");
    _where.add("用户类型");

    if(StrKit.hasValue(searchModel.getLoginId())) {
      _strsql.append(" AND U.LOGIN_ID like ? ");
      _where.add("%" + searchModel.getLoginId() + "%");
    }

    if(StrKit.hasValue(searchModel.getName())) {
      _strsql.append(" AND U.NAME  like ? ");
      _where.add("%" + searchModel.getName()+ "%");
    }

    if(StrKit.hasValue(searchModel.getSex())) {
      _strsql.append(" AND U.SEX  = ? ");
      _where.add(searchModel.getSex());
    }

    if(StrKit.hasValue(searchModel.getUserCode())) {
      _strsql.append(" AND U.USER_TYP  = ? ");
      _where.add(searchModel.getUserCode());
    }



    if(StrKit.hasValue(searchModel.getRoleIds())) {
      _strsql.append(String.format(" AND UR.ROLE_ID  in ("+searchModel.getRoleIds()+") "));
    }

    if(StrKit.hasValue(searchModel.getGroups())) {
      _strsql.append(String.format(" AND UG.GROUP_ID  in ("+searchModel.getGroups()+")"));
    }


    _strsql.append("  GROUP BY  U.ID,\n" +
                     "                  U.LOGIN_ID,\n" +
                     "                  U.CODE,\n" +
                     "                  U.NAME,\n" +
                     "                  r.NAME,\n" +
                     "                  U.USER_TYP,\n" +
                     "                  U.AVATAR, U.ENABLED,U.LAST_LOGIN_TIME,\n" +
                     "                  U.LAST_LOGIN_IP,U.SEX,CODE1.CODENAME,CODE2.CODENAME\n" +
                     "        ORDER BY CODE1.CODENAME,CODE2.CODENAME");

    return TsUser.dao.find(_strsql.toString(), _where.toArray());
  }


  /**
   * 可信账户审核通过
   * @param userids
   * @return
   */
  public TResult auditS(String[]  userids){

    if(userids.length > 0) {
      TsUser _dbmodel;
      for (String id : userids) {
        _dbmodel = TsUser.dao.findById(id);
        if (StrKit.isBlank(_dbmodel.getTrustAccount())) {
          Ret ret = RSAKit.generatorRSA();
          _dbmodel.setPrivateKey(ret.get(RetRes.PRIVATE_KEY).toString());
          _dbmodel.setPublicKey(ret.get(RetRes.PUBLIC_KEY).toString());

          com.jfinal.kit.Ret rets = QuorumKit.createdWallet("");
          String account = rets.getStr("account");

          _dbmodel.setTrustAccount(account);
          _dbmodel.setAccountPrivateKey(rets.getStr(RetRes.PRIVATE_KEY));
          _dbmodel.setAccountPublicKey(rets.getStr(RetRes.PUBLIC_KEY));
          _dbmodel.setTrustName(_dbmodel.getName());
          _dbmodel.setEnabled("1");
          _dbmodel.update();
    ;

        }
      }
      return TResult.success();
    }
    return TResult.fail();
  }

}
